package parse;

import Const.Constant;
import ExecuteEngine.Operation;
import ExecuteEngine.Tuple;
import RecordManagement.ScanType;

public class Boolean_factor {
	public Expression exp;
	public int not;
	public int intValue;
	public String strValue;
	public int op;
	public Attribute ID1;
	public Attribute ID2;
	public int type = 0;
	public String attrName;
	public SFW all;
	public SFW any;
	public SFW in;
	public Operation subquery;
	
	public final static int NOT = 1;
	
	public Boolean_factor(Expression exp, int not){
		this.exp = exp;
		this.not = not;
		this.op = exp.op;
		this.strValue = null;
		this.ID1 = null;
		this.ID2 = null;
		this.attrName = null;
		this.all = null;
		this.any = null;
		this.in = null;
	
		switch(exp.o1.type){
			case Operand.ID:{
				ID1 = exp.o1.id;
				break;
			}
			case Operand.ALL:{
				all = exp.o1.all;
				break;
			}
			case Operand.ANY:{
				any = exp.o1.any;
				break;
			}
			case Operand.INTEGER:{
				intValue = exp.o1.integer;
				type = ScanType.TYPE_INT;
				break;
			}
			case Operand.STRING:{
				strValue = exp.o1.string;
				type = ScanType.TYPE_STRING;
				break;
			}
			case Operand.IN:{
				in = exp.o1.in;
				break;
			}
			case Operand.NULL:{
				break;
			}
			default:
				break;
		}
		
		switch(exp.o2.type){
			case Operand.ID:{
				ID2 = exp.o2.id;
				if(ID1 != null)
					type = 1;
			}
			case Operand.ALL:{
				all = exp.o2.all;
				break;
			}
			case Operand.ANY:{
				any = exp.o2.any;
				break;
			}
			case Operand.INTEGER:{
				intValue = exp.o2.integer;
				type = ScanType.TYPE_INT;
				break;
			}
			case Operand.STRING:{
				strValue = exp.o2.string;
				type = ScanType.TYPE_STRING;
				break;
			}
			case Operand.IN:{
				in = exp.o2.in;
				break;
			}
			case Operand.NULL:{
				break;
			}
			default:
				break;
		}
		
		if(ID1 == null && ID2 != null)
			attrName = ID2.GetAttr_Name();
		else
		if(ID1 != null && ID2 == null)
			attrName = ID1.GetAttr_Name();
		else
			attrName = null;
	}
	
	public boolean Compare(String s){
		boolean mark = false;
		
		switch(this.op){
			case Expression.EQ:
			{
				if(s.equals(strValue))
					mark = true;
				break;
			}
			case Expression.NEQ:
			{
				if(s.equals(strValue))
					mark = false;
				else
					mark = true;
				break;
			}
			default:
				break;
		}
		
		if(not == 1)
			mark = !mark;
		
		return mark;
	}
	
	public boolean Compare(int n){
		boolean mark = false;
		
		switch(this.op){
			case Expression.EQ:
			{
				if(n == intValue)
					mark = true;
				break;
			}
			case Expression.GE:
			{
				if(n >= intValue)
					mark = true;
				break;
			}
			case Expression.GT:
			{
				if(n > intValue)
					mark = true;
				break;
			}
			case Expression.LE:
			{
				if(n <= intValue)
					mark = true;
				break;
			}
			case Expression.LT:
			{
				if(n < intValue)
					mark = true;
				break;
			}
			case Expression.NEQ:
			{
				if(n != intValue)
					mark = true;
				break;
			}
			default:
				break;
		}
		
		if(not == 1)
			mark = !mark;
		
		return mark;
	}
	
	public boolean Compare(String str1, String str2){
		String s1 = null;
		String s2 = null;
		
		if(str1 != null)
			s1 = Tuple.Trim(str1);
		
		if(str2 != null)
			s2 = Tuple.Trim(str2);
		
		boolean mark = false;
		
		switch(this.op){
			case Expression.EQ:
			{
				if(s1.equals(s2))
					mark = true;
				break;
			}
			case Expression.NEQ:
			{
				if(s1.equals(s2))
					mark = false;
				else
					mark = true;
				break;
			}
			default:
				break;
		}
		
		if(not == 1)
			mark = !mark;
		
		return mark;
	}
	
	public boolean Compare(int n1, int n2){
		boolean mark = false;
		
		switch(this.op){
			case Expression.EQ:
			{
				if(n1 == n2)
					mark = true;
				break;
			}
			case Expression.GE:
			{
				if(n1 >= n2)
					mark = true;
				break;
			}
			case Expression.GT:
			{
				if(n1 > n2)
					mark = true;
				break;
			}
			case Expression.LE:
			{
				if(n1 <= n2)
					mark = true;
				break;
			}
			case Expression.LT:
			{
				if(n1 < n2)
					mark = true;
				break;
			}
			case Expression.NEQ:
			{
				if(n1 != n2)
					mark = true;
				break;
			}
			default:
				break;
		}
		
		if(not == 1)
			mark = !mark;
		
		return mark;
	}
}
